package crew.blt.handsound.server.dao.gae;

import java.util.ArrayList;
import java.util.Collection;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;

import crew.blt.handsound.server.dao.UserDAO;
import crew.blt.handsound.server.security.AppRole;
import crew.blt.handsound.shared.domain.Auth;
import crew.blt.handsound.shared.domain.User;

public class UserDAOImpl implements UserDAO{
	
    private static final String USER_TYPE = "GaeUser";
    private static final String USER_ID = "username";
    private static final String USER_USERNAME = "nickname";
    private static final String USER_FIRSTNAME = "forename";
    private static final String USER_LASTNAME = "surname";
    private static final String USER_EMAIL = "email";
    private static final String USER_AUTH = "authorities";
    private static final String USER_ISENABLED = "enabled";
    
	@Override
	public Collection<User> getAll() {
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	    
		Query query = new Query(USER_TYPE);
	    PreparedQuery pq = datastore.prepare(query);
	    
	    ArrayList<User> ret = new ArrayList<User>(); 
	    for (Entity result : pq.asIterable()) {
    		ret.add(entityToUser(result));
    	}
	    return ret;
	}

	@Override
	public User findUser(String userId) {
        Key key = KeyFactory.createKey(USER_TYPE, userId);
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

        try {
            Entity result = datastore.get(key);
            return entityToUser(result);

        } catch (EntityNotFoundException e) {
            return null;
        }
    }

	private User entityToUser(Entity entity){
		User ret = new User(
				(String)entity.getProperty(USER_USERNAME),
	 			(String)entity.getProperty(USER_FIRSTNAME),
	 			(String)entity.getProperty(USER_LASTNAME),
	 			(String)entity.getProperty(USER_EMAIL),
	 			"",
	 			(Boolean)entity.getProperty(USER_ISENABLED)
	 			);
		ret.setId(ret.getUsername());
		
		long binaryAuthorities = (Long)entity.getProperty(USER_AUTH);
        for (AppRole r : AppRole.values()) {
            if ((binaryAuthorities & (1 << r.getBit())) != 0) {
                ret.addAuth(new Auth(ret, r.getAuthType()));
            }
        }
        
		return ret;
	}
}
